local json = require "cjson"
local file = require "pl.file"

-------------------------------------------------------------------------------
---! 内部方法
-------------------------------------------------------------------------------
local config = {}

local function load_config(cfg_file)
    cfg_file = cfg_file or "databin.json"

    ---! 读取文件
    local data = file.read(cfg_file)

    ---! 解析文件
    local conf = json.decode(data)

    ---! 解析配置
    for name, dict in pairs(conf) do repeat
        if type(dict["keys"]) ~= "table" then
            spdlog.warn(string.format("table [%s], [keys] not exists!", name))
            break
        end

        if type(dict["list"]) ~= "table" then
            spdlog.warn(string.format("table [%s], [list] not exists!", name))
            break
        end

        spdlog.debug("import", string.format("Load table : %s ...", name))
        local tick = os.clock()

        local tbl = {}
        for _id, lst in pairs(dict["list"]) do repeat
            id = tonumber(_id)
            if not id then
                spdlog.warn("import", string.format("table [%s], id [%s] is wrong!", name, _id))
                break
            end

            if tbl[id] then
                spdlog.warn("import", string.format("table [%s], id [%s] is duplicate!", name, id))
                break
            end

            tbl[id] = { id = id, }
            for idx, key in ipairs(dict["keys"]) do
                local val = lst[idx]
                if type(val) == "string" then
                    val = string.strip(val)
                end
                tbl[id][key] = val
            end
        until true end

        if tbl then
            config[name] = tbl
        end

        spdlog.debug("import", string.format("Load table : %s OK, items count = %d, cost tick = %s.", name, table.size(tbl), os.clock() - tick))
    until true end
end

-------------------------------------------------------------------------------
---! 对外接口
-------------------------------------------------------------------------------
IMPORT_D = {}

function IMPORT_D:get_table(tbl_name)
    return config[tbl_name] or nil
end

function IMPORT_D:load(cfg_file)
    local tick = os.clock()
    local old_config, config = config, {}
    local ok = xpcall(load_config, error_traceback, cfg_file)
    if not ok then
        config = old_config
        return false
    end

    IMPORT_D:init()
    local cost = os.clock() - tick
    spdlog.debug("import", string.format("Load all tables OK. cost total tick = %s", cost))
    return true
end

function IMPORT_D:init()
    ---! 重置配置表
    IMPORT_D.CONFIG_TABLE = {}

    ---! 重新加载
    update_all("import", true)
end

function IMPORT_D:set(table_name, table)
    assert(type(table) == "table")
    if not IMPORT_D.CONFIG_TABLE then
        IMPORT_D.CONFIG_TABLE = {}
    end
    IMPORT_D.CONFIG_TABLE[table_name] = table
end

function IMPORT_D:query(table_name)
    if not IMPORT_D.CONFIG_TABLE then
        IMPORT_D:init()
    end

    if IMPORT_D.CONFIG_TABLE[table_name] then
        return IMPORT_D.CONFIG_TABLE[table_name]
    end

    return IMPORT_D:get_table(table_name) or {}
end
